﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Specialized;
using System.Xml;
using System.ComponentModel;
using System.Collections.ObjectModel;

/// <summary>
/// Summary description for UrlRewriting
/// </summary>
/// 
namespace HSM.Web.UI
{
    [Serializable]
    public class UrlRewriteConfig
    {
        public string RequestUrl { get; set; }
        public string TransferUrl { get; set; }
        public int ThemeID { get; set; }
        public int ClientID { get; set; }

        public static UrlRewriteConfigCollection LoadUrlConfig()
        {
            string configFile = HttpContext.Current.Server.MapPath("~/App_Data/URLConfigs.xml");
            XmlDocument doc = new XmlDocument();
            doc.Load(configFile);
            XmlNodeList nodes = null;
            
            nodes = doc.SelectNodes("//configs/page");
            if (nodes.Count == 0) return null;
            UrlRewriteConfigCollection configs = new UrlRewriteConfigCollection();
            for (int i = 0; i < nodes.Count; i++)
            {
                UrlRewriteConfig item = new UrlRewriteConfig();
                item.RequestUrl = nodes[i].Attributes["request"].Value;
                item.TransferUrl = nodes[i].Attributes["transferTo"].Value;
                configs.Add(item);
            }
            return configs;
        }
    }
    [Serializable]
    public class UrlRewriteConfigCollection : Collection<UrlRewriteConfig>
    {
        public UrlRewriteConfig FindByCurrentRequest()
        {
            HttpContext context = HttpContext.Current;
            foreach (UrlRewriteConfig config in this.Items)
            {
                string configRequestUrl = config.RequestUrl.ToLower();
                string currentRequestUrl = string.Empty;
               
                if (configRequestUrl.Contains("~"))
                {
                    // Sub Folder
                    configRequestUrl = HttpUtility.UrlDecode(VirtualPathUtility.ToAbsolute(configRequestUrl).ToLower());
                    currentRequestUrl = HttpUtility.UrlDecode(context.Request.RawUrl.ToLower());                    
                }
                else
                {
                    // Sub Domain
                    currentRequestUrl = context.Request.Url.Host + context.Request.Url.PathAndQuery;
                    configRequestUrl = HttpUtility.UrlDecode(configRequestUrl);
                }

                if (currentRequestUrl.Equals(configRequestUrl, StringComparison.OrdinalIgnoreCase))
                {
                    return config;
                }
            }           
            return null;
        }
    }

    public class UrlRewriting : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(DoBeginRequest);
            context.PreRequestHandlerExecute += new EventHandler(DoPreRequestHandlerExecute);
        }

        private void DoPreRequestHandlerExecute(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
            if (app.Context.CurrentHandler is Page && app.Context.CurrentHandler != null)
            {
                Page pg = (Page)app.Context.CurrentHandler;
                pg.PreRenderComplete += new EventHandler(DoPreRenderComplete);
            }
        }

        private void DoPreRenderComplete(object sender, EventArgs e)
        {
            if (HttpContext.Current.Items.Contains("_OrgUrl"))
            {
                string path = (string)HttpContext.Current.Items["_OrgUrl"];
                HttpContext.Current.RewritePath(path, "", HttpContext.Current.Items["_OrgUrlQuery"].ToString());
            }
        }
         
        private void DoBeginRequest(object sender, EventArgs e)
        {
            UrlRewriteConfigCollection configs = HSMCacheManager.LoginUrlConfigs;
            HttpContext context = HttpContext.Current;

            //Force SSL
            bool forceSSL = ConfigurationManager.AppSettings["ForceSSL"] == "true";
            if (HSMConfigurations.IsForceSSL && !HSMConfigurations.IsSchemeSSL)
            {
                context.Response.Redirect(context.Request.Url.AbsoluteUri.ToLower().Replace("http://", "https://"));
                return;
            }
            // Rewrite URL
            if (this.IsRewriting && configs!=null)
            {
                UrlRewriteConfig tranfer = configs.FindByCurrentRequest();
                if (tranfer != null)
                {
                    this.DoRewriteURL(tranfer.TransferUrl);
                }
            }
        }
        private void DoRewriteURL(string transferUrl)
        {
            HttpContext context = HttpContext.Current;           
            string paramUrl = context.Request.QueryString.Count == 0 ? string.Empty : context.Request.QueryString.ToString();
            if (!string.IsNullOrEmpty(paramUrl))transferUrl += "&" + paramUrl;
            //save for PreRenderComplete
            context.Items.Add("_OrgUrl", context.Request.Url.AbsolutePath);
            context.Items.Add("_OrgUrlQuery", paramUrl);
            context.RewritePath(transferUrl);
        }
        private bool IsRewriting
        {
            get 
            {
                string executionFilePath = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath;
                executionFilePath = executionFilePath.Replace("~/", string.Empty);
                return string.IsNullOrEmpty(executionFilePath.Trim());
            }
        }

        public void Dispose() 
        {
 
        }
    }
}